package auth

import (
	"5title_gin/global"
	"5title_gin/internal/api/middleware"
	"5title_gin/internal/model/user"
	"5title_gin/internal/service/auth"
	"5title_gin/pkg/utils/http"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

type AuthAPI struct {
	service *auth.AuthService
}

func NewUserAPI() *AuthAPI {
	return &AuthAPI{
		service: auth.NewAuthService(),
	}
}

// LoginView 用户登录
// @Tags 用户管理
// @Summary 用户登录
// @Description 用户登录
// @Param data body LoginRequest true "参数"
// @Router /api/users/login [post]
// @Produce json
// @Success 200 {object} http.Response
func (api *AuthAPI) LoginView(c *gin.Context) {
	cr := middleware.GetBind[user.LoginRequest](c)

	// 调用服务层登录
	accessToken, refreshToken, err := api.service.Login(cr)
	if err != nil {
		http.FailWithMsg(err.Error(), c)
		return
	}

	// 构造返回数据
	var data = struct {
		AccessToken  string `json:"accessToken"`
		RefreshToken string `json:"refreshToken"`
	}{
		AccessToken:  accessToken,
		RefreshToken: refreshToken,
	}

	// 返回成功响应
	http.Ok(data, "登录成功", c)
}

// RefreshToken 刷新 Token
func (api *AuthAPI) RefreshToken(c *gin.Context) {
	cr := middleware.GetBind[user.RefreshTokenRequest](c)
	zap.S().Info("refreshToken", cr.RefreshToken)

	// 调用服务层刷新Token
	newAccessToken, err := api.service.RefreshToken(cr.RefreshToken)
	if err != nil {
		http.FailWithMsg(err.Error(), c)
		return
	}

	http.Ok(newAccessToken, "刷新成功", c)
}

func (api *AuthAPI) EditPwd(c *gin.Context) {
	// 解析请求体
	cr := middleware.GetBind[user.Password](c)

	// 获取用户ID
	userID, exists := c.Get("userID")
	if !exists {
		http.FailWithMsg("获取用户ID失败", c)
		return
	}

	// 调用服务层修改密码
	err := api.service.ChangePassword(userID.(uint), cr.OldPassword, cr.NewPassword)
	if err != nil {
		http.FailWithMsg(err.Error(), c)
		return
	}

	http.OkWithMsg("修改密码成功", c)
}

// LogoutView 登出
// @Tags 用户管理
// @Summary 登出
// @Description 登出
// @Router /api/logout [post]
// @Produce json
// @Success 200 {object} http.Response{}
func (api *AuthAPI) LogoutView(c *gin.Context) {
	token := c.GetHeader("Authorization")[7:]
	if global.Redis == nil {
		http.OkWithMsg("注销成功", c)
		return
	}
	value, exists := c.Get("userID")
	if !exists {
		http.FailWithMsg("获取用户ID失败", c)
		return
	}
	userID := value.(uint)
	if err := api.service.Logout(token, userID); err != nil {
		http.FailWithMsg(err.Error(), c)
		return
	}
	http.OkWithMsg("注销成功", c)

}
